﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TestCenter.Platform.DataModel;
using RapidWebDev.Common.Data;
using RapidWebDev.Platform;
using System.Collections.ObjectModel;
using RapidWebDev.Platform.Linq;

namespace TestCenter.Platform.Apis
{
    public class TestCenterApi : ITestCenterApi
    {
        private IHierarchyApi hierarchyApi;
        private IAuthenticationContext authenticationContext;

        public TestCenterApi(HierarchyApi hierarchyApi, IAuthenticationContext authenticationContext)
        {
            this.hierarchyApi = hierarchyApi;
            this.authenticationContext = authenticationContext;
        }


        #region ITestCenterApi Members

        public IEnumerable<TestProject> GetAllTestProject()
        {
            using (TestCenterDataContext ctx = DataContextFactory.Create<TestCenterDataContext>())
            {
                return ctx.TestProjects;
            }
        }

        public Collection<HierarchyDataObject> GetChildrenTreeNode(string parentId, string testCenterHierarchyType, Collection<HierarchyDataObject> nodes)
        {
            IEnumerable<HierarchyDataObject> results;
            //add parent first
            //LinqPredicate predicate = new LinqPredicate("Code=@0 AND HierarchyType=@1", parentId, testCenterHierarchyType);
            //int recordCount;
            var tmpFirst = hierarchyApi.GetHierarchyData(new Guid(parentId));
            if (!nodes.Contains(tmpFirst))
                nodes.Add(tmpFirst);

            switch (testCenterHierarchyType)
            {
                case "0":
                    results = hierarchyApi.GetAllChildren("0", new Guid(parentId));
                    foreach (HierarchyDataObject tmp in results)
                    {
                        nodes.Add(tmp);

                        //return GetChildrenTreeNode(tmp.HierarchyDataId.ToString(), "0", nodes);
                    }
                    break;
                case "1"://testsuite
                    results = hierarchyApi.GetAllChildren("1", new Guid(parentId));
                    foreach (HierarchyDataObject tmp in results)
                    {
                        nodes.Add(tmp);
                        //return GetChildrenTreeNode(tmp.HierarchyDataId.ToString(), "1", nodes);
                    }
                    break;
                case "2"://testplan
                    results = hierarchyApi.GetAllChildren("2", new Guid(parentId));
                    foreach (HierarchyDataObject tmp in results)
                    {
                        nodes.Add(tmp);

                        //return GetChildrenTreeNode(tmp.HierarchyDataId.ToString(), "2", nodes);
                    }
                    break;
                case "3":
                    break;
                case "4":
                    break;
            }
            return nodes;
        }

        public string SaveTestProject(TestCenter.Platform.DataModel.TestProject entity, string ParentId)
        {
            using (TestCenterDataContext ctx = DataContextFactory.Create<TestCenterDataContext>())
            {

                //save TestProject firstly
                ctx.TestProjects.InsertOnSubmit(entity);

                ctx.SubmitChanges();


                HierarchyDataObject hierarchyDataObject = new HierarchyDataObject()
                {
                    Code = entity.Id.ToString(),
                    Name = entity.Name,
                    HierarchyType = "0"
                };
                if (!string.IsNullOrEmpty(ParentId) && entity.IsParent == true)
                    hierarchyDataObject.ParentHierarchyDataId = new Guid(ParentId);               

                hierarchyApi.Save(hierarchyDataObject);

                return entity.Id.ToString();
            }
        }

        public string SaveTestSuite(TestCenter.Platform.DataModel.TestSuite entity, string ParentId)
        {
            using (TestCenterDataContext ctx = DataContextFactory.Create<TestCenterDataContext>())
            {
                //save TestProject firstly
                ctx.TestSuites.InsertOnSubmit(entity);
                ctx.SubmitChanges();

                HierarchyDataObject hierarchyDataObject = new HierarchyDataObject()
                {
                    Code = entity.Id.ToString(),//为实体的 Guid
                    Name = entity.Name,
                    HierarchyType = "1"
                };
                if (!string.IsNullOrEmpty(ParentId))
                    hierarchyDataObject.ParentHierarchyDataId = new Guid(ParentId);

                hierarchyApi.Save(hierarchyDataObject);

                return hierarchyDataObject.HierarchyDataId.ToString();
            }
        }

        public string SaveTestCase(TestCenter.Platform.DataModel.TestCase entity, string ParentId)
        {
            using (TestCenterDataContext ctx = DataContextFactory.Create<TestCenterDataContext>())
            {
                //save TestProject firstly
                ctx.TestCases.InsertOnSubmit(entity);
                ctx.SubmitChanges();

                HierarchyDataObject hierarchyDataObject = new HierarchyDataObject()
                {
                    Code = entity.Id.ToString(),
                    Name = entity.Name,
                    HierarchyType = "2"
                };
                if (!string.IsNullOrEmpty(ParentId))
                    hierarchyDataObject.ParentHierarchyDataId = new Guid(ParentId);

                hierarchyApi.Save(hierarchyDataObject);

                return hierarchyDataObject.HierarchyDataId.ToString();
            }
        }

        public string SaveBuild(TestCenter.Platform.DataModel.Build entity, string ParentId)
        {
            using (TestCenterDataContext ctx = DataContextFactory.Create<TestCenterDataContext>())
            {
                //save TestProject firstly
                ctx.Builds.InsertOnSubmit(entity);
                ctx.SubmitChanges();

                HierarchyDataObject hierarchyDataObject = new HierarchyDataObject()
                {
                    Code = entity.Id.ToString(),
                    Name = entity.Name,
                    HierarchyType = "4"
                };
                if (!string.IsNullOrEmpty(ParentId))
                    hierarchyDataObject.ParentHierarchyDataId = new Guid(ParentId);

                hierarchyApi.Save(hierarchyDataObject);

                return hierarchyDataObject.HierarchyDataId.ToString();
            }
        }

        public string SaveTestPlan(TestCenter.Platform.DataModel.TestPlan entity, string ParentId)
        {
            using (TestCenterDataContext ctx = DataContextFactory.Create<TestCenterDataContext>())
            {
                //save TestProject firstly
                ctx.TestPlans.InsertOnSubmit(entity);
                ctx.SubmitChanges();

                HierarchyDataObject hierarchyDataObject = new HierarchyDataObject()
                {
                    Code = entity.Id.ToString(),
                    Name = entity.Name,
                    HierarchyType = "3"
                };
                if (!string.IsNullOrEmpty(ParentId))
                    hierarchyDataObject.ParentHierarchyDataId = new Guid(ParentId);

                hierarchyApi.Save(hierarchyDataObject);

                return hierarchyDataObject.HierarchyDataId.ToString();
            }
        }

        public TestCenter.Platform.DataModel.TestProject GetTestProjectById(Guid entityId)
        {
            using (TestCenterDataContext ctx = DataContextFactory.Create<TestCenterDataContext>())
            {
                return ctx.TestProjects.Where(x => x.Id == entityId).FirstOrDefault();
            }
        }

        public TestCenter.Platform.DataModel.TestSuite GetTestSuiteById(Guid entityId)
        {
            using (TestCenterDataContext ctx = DataContextFactory.Create<TestCenterDataContext>())
            {
                return ctx.TestSuites.Where(x => x.Id == entityId).FirstOrDefault();
            }
        }

        public TestCenter.Platform.DataModel.TestCase GetTestCaseById(Guid entityId)
        {
            using (TestCenterDataContext ctx = DataContextFactory.Create<TestCenterDataContext>())
            {
                return ctx.TestCases.Where(x => x.Id == entityId).FirstOrDefault();
            }
        }

        public TestCenter.Platform.DataModel.TestPlan GetTestPlanById(Guid entityId)
        {
            using (TestCenterDataContext ctx = DataContextFactory.Create<TestCenterDataContext>())
            {
                return ctx.TestPlans.Where(x => x.Id == entityId).FirstOrDefault();
            }
        }

        public TestCenter.Platform.DataModel.Build GetBuildById(Guid entityId)
        {
            using (TestCenterDataContext ctx = DataContextFactory.Create<TestCenterDataContext>())
            {
                return ctx.Builds.Where(x => x.Id == entityId).FirstOrDefault();
            }
        }

        public Collection<TestCenter.Platform.DataModel.TestProject> FindTestProjects(LinqPredicate predicate, string orderby, int pageIndex, int pageSize, out int recordCount)
        {
            throw new NotImplementedException();
        }

        public Collection<TestCenter.Platform.DataModel.TestSuite> FindTestSuites(LinqPredicate predicate, string orderby, int pageIndex, int pageSize, out int recordCount)
        {
            throw new NotImplementedException();
        }

        public Collection<TestCenter.Platform.DataModel.TestCase> FindTestCases(LinqPredicate predicate, string orderby, int pageIndex, int pageSize, out int recordCount)
        {
            throw new NotImplementedException();
        }

        public Collection<TestCenter.Platform.DataModel.TestPlan> FindTestPlans(LinqPredicate predicate, string orderby, int pageIndex, int pageSize, out int recordCount)
        {
            throw new NotImplementedException();
        }

        public Collection<TestCenter.Platform.DataModel.Build> FindBuilds(LinqPredicate predicate, string orderby, int pageIndex, int pageSize, out int recordCount)
        {
            throw new NotImplementedException();
        }

        public void DeleteTestProject(Guid entityId)
        {
            throw new NotImplementedException();
        }

        public void DeleteTestSuite(Guid entityId)
        {
            throw new NotImplementedException();
        }

        public void DeleteTestCase(Guid entityId)
        {
            throw new NotImplementedException();
        }

        public void DeleteTestPlan(Guid entityId)
        {
            throw new NotImplementedException();
        }

        public void DeleteBuild(Guid entityId)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Assign testcase , testsuite to specific testplan
        /// </summary>
        /// <param name="testCaseIds"></param>
        /// <param name="testsuiteId"></param>
        /// <param name="testplanId"></param>
        public void AssignTestCaseToTestPlan(IEnumerable<string> testCaseIds,string testsuiteId, string testplanId) 
        {
            IList<TestCaseResult> results = new List<TestCaseResult>();
            using (TestCenterDataContext ctx = DataContextFactory.Create<TestCenterDataContext>())
            {
                foreach (var testcaseid in testCaseIds)
                {
                    TestCaseResult result = new TestCaseResult()
                    {
                        TestCaseId = new Guid(testcaseid),
                        TestPlanId = new Guid(testplanId),
                        TestProjectId = new Guid(authenticationContext.Session["CurrentProject"].ToString()),
                        TestSuiteId = new Guid(testsuiteId),
                        Status = ResultStatus.NotRun
                    };
                    results.Add(result);       
                }
                Testplan_Testcase testplan_testcase = new Testplan_Testcase() 
                { createdOn = DateTime.Now,createdBy = authenticationContext.User.UserId, TestPlanId = new Guid(testplanId),TestSuiteId = new Guid(testsuiteId)};

                ctx.Testplan_Testcases.InsertOnSubmit(testplan_testcase);

                ctx.TestCaseResults.InsertAllOnSubmit(results);
                ctx.SubmitChanges();
            }
        }

        #endregion
    }
}
